# python高级特性
#一 切片
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']  # 取前三个元素
print(L[0], L[1], L[2])   # 要是取N个呢,很麻烦吧?因此，Python提供了切片（Slice）操作符，能大大简化这种操作。
print(L[0:3]) # 表示，从索引0开始取，直到索引3为止，但不包括索引3。即索引0，1，2，正好是3个元素,如果第一个索引是0，还可以省略：
print(L[:4])
print(L[1:3]) #也可以从索引1开始,取出2个元素
print(L[-1])  # 最后一个:
print(L[-4:-1]) # 从取-4索引开始,到-1前结束
print(L[-3:])   #取倒数三个

print(range(100)) # 生成一个0-99的序列
L = list(range(100))
print(L[:10]) #取前十个
print(L[-10:]) #取后十个
print(L[11:20]) #取11-20个数
print(L[:10:2]) #前十个,每两个取一个
print(L[::5]) #所有数,每五个取一个
print(L[:]) #什么都不写  复制一个原来的

# tuple也是一种list，唯一区别是tuple不可变。因此，tuple也可以用切片操作，只是操作的结果仍是tuple：
print((0, 1, 2, 3, 4, 5)[:3])
# 字符串'xxx'也可以看成是一种list，每个元素就是一个字符。因此，字符串也可以用切片操作，只是操作结果仍是字符串：
print('ABCDEFG'[:3])
print('ABCDEFG'[::2])
print("-------------------------------------------------------------------------------")
# 在很多编程语言中，针对字符串提供了很多各种截取函数（例如，substring），其实目的就是对字符串切片。Python没有针对字符串的截取函数，只需要切片一个操作就可以完成，非常简单。

#二 迭代
# 如果给定一个list或tuple，我们可以通过for循环来遍历这个list或tuple，这种遍历我们称为迭代（Iteration）。
d = ['a','n',1,6];
for key in d:
	print(key)
print("-------------------------------------------------------------------------------")

# list这种数据类型虽然有下标，但很多其他数据类型是没有下标的，但是，只要是可迭代对象，无论有无下标，都可以迭代，比如dict就可以迭代：
d = {'a':3,'c':8,5:'d'}
for key in d:
	print(key)
print("-------------------------------------------------------------------------------")
# 因为dict的存储不是按照list的方式顺序排列，所以，迭代出的结果顺序很可能不一样
# 默认情况下，dict迭代的是key。如果要迭代value，可以用for value in d.values()，如果要同时迭代key和value，可以用for k, v in d.items()。
for val in d.values():
	print(val)
for k,v in d.items():
	print(k,':',v)
print("-------------------------------------------------------------------------------")
# 由于字符串也是可迭代对象，因此，也可以作用于for循环：
for ch in "AFD":
	print(ch)
# 当我们使用for循环时，只要作用于一个可迭代对象，for循环就可以正常运行，而我们不太关心该对象究竟是list还是其他数据类型。那么，如何判断一个对象是可迭代对象呢？方法是通过collections模块的Iterable类型判断：
from collections import Iterable
print(isinstance('sdf',Iterable))	 # str是否可迭代
print(isinstance((8,2,5,6),Iterable))	 # tuple是否可迭代
print(isinstance(123,Iterable))	 # 整型是否可迭代
# 如果要对list实现类似Java那样的下标循环怎么办？Python内置的enumerate函数可以把一个list变成索引-元素对，这样就可以在for循环中同时迭代索引和元素本身：
for k,v in enumerate(['A','B','C']):
	print(k, v)
# 同时引用了两个变量，在Python里是很常见的，比如下面的代码：
for x, y in [(1, 1), (2, 4), (3, 9)]:
    print(x, y)
for x, y, z in [(1, 1, 5), (2, 4, 5), (3, 9, 8)]:
    print(x, y, z)

#三 列表生成式  可以用来创建list的生成式
# 要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)), 但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做？方法一是循环：
L = []
for x in list(range(1,11)):
	L.append(x*x)
print(L)
# 但是循环太繁琐，而列表生成式则可以用一行语句代替循环生成上面的list：
P = [x*x for x in range(1,11)]
print(P)
# for循环后面还可以加上if判断，这样我们就可以筛选出仅偶数的平方：
Q = [x*x for x in range(1,11) if x%2 == 0]
print(Q)	
# 还可以使用两层循环，可以生成全排列：
W = [x+c for x in "ABc" for c in "QWE"]
print(W)
E = [x*c for x in range(1,5) for c in range(5,11)]
print(E)	
# 运用列表生成式，可以写出非常简洁的代码。例如，列出当前目录下的所有文件和目录名，可以通过一行代码实现：
import os # 导入os模块
print([d for d in os.listdir('.')])	 # os.listdir可以列出文件和目录
print([d for d in os.listdir('..')]) #列出上级目录下的文件和目录
# dict的items()可以同时迭代key和value, 因此，列表生成式也可以使用两个变量来生成list：
print([k+"="+v for k,v in {"A":'a', 'B':'b', 'C':'c'}.items()])	
# 把一个list中所有的字符串变成小写：
R = ['Hello', 'World', 'IBM', 'HuaWei']
print([s.lower() for s in R])
# 如果list中既包含字符串，又包含整数，由于非字符串类型没有lower()方法，所以列表生成式会报错, 使用内建的isinstance函数可以判断一个变量是不是字符串：
T = ['Hello', 'World', 18, 'IBM', 88, 'HuaWei']
print([s.lower() for s in T if isinstance(s, str)])	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

